package pb

import (
	log "github.com/golang/glog"
	"google.golang.org/protobuf/proto"
)

type MessagePacketParser struct {
	buffer []byte
}

func MarshalMessagePacket(packet *Packet) ([]byte, error) {
	buffer, err := proto.Marshal(packet)
	if err != nil {
		return nil, err
	}
	l := len(buffer)
	frame := []byte{0xFF, 0xFF, 0xFF, 0xFF, byte((l >> 24) & 0xFF), byte((l >> 16) & 0xFF), byte((l >> 8) & 0xFF), byte(l & 0xFF)}
	frame = append(frame, buffer...)
	return frame, nil
}

func (p *MessagePacketParser) PushData(data []byte, callback func(frame []byte, packet *Packet)) {
	p.buffer = append(p.buffer, data...)
	for {
		frame, buffer := p.findFrame()
		p.buffer = buffer
		if frame == nil {
			break
		}

		pkt := Packet{}
		err := proto.Unmarshal(frame[8:], &pkt)
		if err != nil {
			log.Error("解析Packet消息失败:", err)
		} else {
			tmp := make([]byte, len(frame))
			copy(tmp, frame)
			callback(tmp, &pkt)
		}
	}
}

func (p *MessagePacketParser) findFrame() ([]byte, []byte) {
	if len(p.buffer) < 10 {
		return nil, p.buffer
	}
	end := len(p.buffer) - 8
	for i := 0; i < end; i++ {
		if p.buffer[i] == 0xFF && p.buffer[i+1] == 0xFF && p.buffer[i+2] == 0xFF && p.buffer[i+3] == 0xFF {
			l := int(p.buffer[i+4])<<24 | int(p.buffer[i+5])<<16 | int(p.buffer[i+6])<<8 | int(p.buffer[i+7])
			if i+l+8 > len(p.buffer) {
				return nil, p.buffer
			}
			return p.buffer[i : i+l+8], p.buffer[i+l+8:]
		}
	}
	return nil, p.buffer
}
